//package com.gk.panda.interceptor;
//
//import com.alibaba.fastjson.JSONObject;
//import com.gk.panda.apis.service.UserService;
//import com.gk.panda.commons.result.Result;
//import com.gk.panda.commons.rsa.RsaService;
//import com.gk.panda.pojo.UrlInfo;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.tomcat.util.http.MimeHeaders;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.data.redis.core.ValueOperations;
//import org.springframework.stereotype.Component;
//import org.springframework.util.AntPathMatcher;
//import org.springframework.web.servlet.HandlerInterceptor;
//
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.io.PrintWriter;
//import java.lang.reflect.Field;
//import java.util.Arrays;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.TimeUnit;
//
///**
// * @Description:
// * @author: wangchao
// * @date: 2023/3/14 11:04
// * @version: 1.0
// **/
//@Component
//public class AuthorizationInterceptor implements HandlerInterceptor {
//
//    private static final List<UrlInfo> EXCLUDE_URLS = Arrays.asList(
//            new UrlInfo("/kaptcha","get"),
//            new UrlInfo("/file/upload","post"),
//            new UrlInfo("/file/del","get"),
//            new UrlInfo("/file/download","post"),
//            new UrlInfo("/edmp/largeScreen/getLoginBack","get"),
//            new UrlInfo("/edmp/largeScreen/downloadPatrolAPPUrl","get"),
//            new UrlInfo("/umwcamera/getListOfApp","post")
//    );
//
//    @Autowired
//    private RsaService rsaService;
//
//    @Autowired
//    private UserService userService;
//
//    @Autowired
//    private RedisTemplate<String,Object> redisTemplate;
//
//    @Override
//    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        String uri = request.getRequestURI();
//        String contextPath = request.getContextPath();
//        String url = uri.replace(contextPath, "");
//        String method = request.getMethod();
//        if (comparison(EXCLUDE_URLS,url,method)) {
//            return true;
//        }
//        String token = request.getHeader("Authorization");
//        if (StringUtils.isEmpty(token)){
//            writeResult(response, Result.error(102,"请先登录"));
//            return false;
//        }
//
//        try {
//            Map<String, Object> map = rsaService.parseToken(token);
////            Object orgId = map.get("orgId");
////            String orgName = (String) map.get("orgName");
//            String username = (String) map.get("username");
////            String orgAbbr = (String) map.get("orgAbbr");
////            String name = (String) map.get("name");
//            String loginWay = (String) map.get("loginWay");
////            reflectSetHeader(request,"orgId",orgId.toString());
////            reflectSetHeader(request,"orgName", URLEncoder.encode(orgName, "utf-8"));
////            reflectSetHeader(request,"username",URLEncoder.encode(username, "utf-8"));
////            reflectSetHeader(request,"orgAbbr",orgAbbr);
////            reflectSetHeader(request,"name",URLEncoder.encode(name, "utf-8"));
//            ValueOperations<String,Object> ops = redisTemplate.opsForValue();
//            String redisToken = (String) ops.get(loginWay + "-access_token::" + username);
//            if (token.equals(redisToken)) {//token验证通过
//                response.setHeader("access_token",token);//放入响应
//                response.setHeader("Access-Control-Expose-Headers","access_token");
//                List<UrlInfo> urlInfos = (List<UrlInfo>) ops.get("permission::" + username);
//                if (urlInfos == null) {//Redis中没有就去数据库中查
//                    urlInfos = userService.getUserPermission(username);
//                    List<UrlInfo> exclude = userService.getExcludeUrl();
//                    urlInfos.addAll(exclude);
//                    ops.set("permission::" + username, urlInfos, 10, TimeUnit.MINUTES);
//                }
//                boolean hasPermission = false;//默认没有权限
//                if (loginWay.equals("APP/LS")) hasPermission = true;
//                if (comparison(urlInfos,url,method)){
//                    hasPermission = true;
//                }
//
//                if (hasPermission) {//有权限
//                    return true;
//                } else {//没有权限
//                    writeResult(response, Result.error(103,"没有权限"));
//                    return false;
//                }
//            } else {//token验证未通过
//                writeResult(response, Result.error(102,"用户认证未通过"));
//                return false;
//            }
//        } catch (Exception e) {//token解析错误
//            e.printStackTrace();
//            writeResult(response,Result.error(102,"无效的票据"));
//            return false;
//        }
//    }
//
//    private boolean comparison(List<UrlInfo> urlInfos,String url,String method) {
//        AntPathMatcher matcher = new AntPathMatcher();
//        for (UrlInfo urlInfo : urlInfos) {
//            String redisUrl = urlInfo.getUrl();
//            String[] dbUrls;
//            String[] dbMethods;
//            if (redisUrl.contains(",")){
//                dbUrls = redisUrl.split(",");
//                dbMethods = urlInfo.getMethod().split(",");
//            } else {
//                dbUrls = new String[]{redisUrl};
//                dbMethods = new String[]{urlInfo.getMethod()};
//            }
//            for (int i = 0; i < dbUrls.length; i++) {
//                if (matcher.match(dbUrls[i],url)&&method.equalsIgnoreCase(dbMethods[i])){
//                    return true;
//                }
//            }
//        }
//        return false;
//    }
//
//    private <T> void writeResult(HttpServletResponse response, Result<T> result) throws IOException {
//        response.setContentType("application/json;charset=utf-8");
//        response.setCharacterEncoding("UTF-8");
//        PrintWriter writer = response.getWriter();
//        String json = JSONObject.toJSONString(result);
//        writer.print(json);
//        writer.flush();
//    }
//
//    private void reflectSetHeader(HttpServletRequest request, String key, String value){
//        Class<? extends HttpServletRequest> requestClass = request.getClass();
//        try {
//            Field requestField = requestClass.getDeclaredField("request");
//            requestField.setAccessible(true);
//            Object requestObj = requestField.get(request);
//            Field coyoteRequestField = requestObj.getClass().getDeclaredField("coyoteRequest");
//            coyoteRequestField.setAccessible(true);
//            Object coyoteRequestObj = coyoteRequestField.get(requestObj);
//            Field headersField = coyoteRequestObj.getClass().getDeclaredField("headers");
//            headersField.setAccessible(true);
//            MimeHeaders headersObj = (MimeHeaders)headersField.get(coyoteRequestObj);
//            headersObj.removeHeader(key);
//            headersObj.addValue(key).setString(value);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//}
